package com.mate.cloud.hot.service.impl;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.mate.cloud.hot.service.HotKeyDetectionService;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

@Service
public class HotKeyDetectionServiceImpl implements HotKeyDetectionService {


    private final Cache<String, Object> localCache = Caffeine.newBuilder()
            .expireAfterWrite(10, TimeUnit.SECONDS)
            .maximumSize(1000)
            .build();

    // 用于统计Key的访问频率
    private final ConcurrentHashMap<String, AtomicLong> accessCounter = new ConcurrentHashMap<>();

    @Resource
    private RedisTemplate<String, Object> redisTemplate;


    @Override
    public Object getWithHotKeyDetection(String key) {
        // 统计访问次数
        accessCounter.computeIfAbsent(key, k -> new AtomicLong(0)).incrementAndGet();

        // 先查本地缓存
        Object value = localCache.getIfPresent(key);
        if (value != null) {
            return value;
        }

        // 查Redis
        value = redisTemplate.opsForValue().get(key);
        if (value != null) {
            // 如果是热点Key，加入本地缓存
            if (isHotKey(key)) {
                localCache.put(key, value);
            }
        }

        return value;
    }

    /**
     * 定时清理访问计数器（每分钟一次）
     */
    @Scheduled(fixedRate = 60000)
    @Override
    public void clearAccessCounter() {
        accessCounter.clear();
    }

    /**
     * 判断是否为热点Key（阈值可根据实际情况调整）
     */
    private boolean isHotKey(String key) {
        AtomicLong counter = accessCounter.get(key);
        return counter != null && counter.get() > 1000; // 阈值设为1000次
    }
}
